
1;


################################################################################
#                                                                           ##
#spread                                                                     ##
#                                                                           ##
################################################################################

function distance = nearest_neighborg_distance(real_pareto_front, solution, idx)
    min_d_i = realmax;
    for i = 1 : rows(real_pareto_front)
        solution_front = real_pareto_front(i, :);
        if (i != idx)
            d_i = euclidean_distance(solution_front, solution);
            if (d_i < min_d_i)
                min_d_i = d_i;
            endif
        endif
    endfor
    distance = min_d_i;
endfunction

function distance = nearest_to_extreme_i(extreme, pareto_front, m)
    min_d_i = realmax;
    for i = 1 : rows(pareto_front)
        front_solution = pareto_front(i, :);
        d_i = abs(extreme(m) - front_solution(m));
        if (d_i < min_d_i)
            min_d_i = d_i;
        endif
    endfor
    distance = min_d_i;
endfunction

function sum_distance = sum_extremes_distance(extremes, pareto_front)
    sum_distance = 0;
    for i = 1 : rows(extremes)
        extreme = extremes(i, :);
        for j = 1 : columns(extremes)
            sum_distance = sum_distance + nearest_to_extreme_i(extreme, pareto_front, j);
        endfor
    endfor
endfunction


function value = spread(extremes, pareto_front)

    fprintf(stderr, "evaluating spread\n");
    d = zeros(rows(pareto_front), 1);
    sum_d = 0;
    for i = 1 : rows(pareto_front)
        fprintf(stderr, "\tevaluating distance ... %d/%d\r", i, rows(pareto_front));
        d(i) = nearest_neighborg_distance(pareto_front, pareto_front(i,:), i);
        sum_d = sum_d + d(i);
    endfor
    fprintf(stderr, "\tevaluating distance ... \t[done]\n", i, rows(pareto_front));
    average_d = sum_d / rows(pareto_front);

    sum_extremes = sum_extremes_distance(extremes, pareto_front);

    sum_d = 0;
    for i = 1 : rows(d)
        sum_d = abs(average_d - d(i));
    endfor

    value = (sum_extremes + sum_d) / (sum_extremes + rows(pareto_front)*average_d);

endfunction
